<template>
  <div class="game-canvas-container">
    <canvas 
      ref="canvasRef"
      :id="canvasId"
      class="game-canvas"
      :width="canvasWidth"
      :height="canvasHeight"
      @click="handleCanvasClick"
      @keydown="handleKeyDown"
      @keyup="handleKeyUp"
      tabindex="0"
    />
    <div v-if="isLoading" class="loading-overlay">
      <div class="loading-spinner"></div>
      <p>游戏加载中...</p>
    </div>
    <div v-if="error" class="error-overlay">
      <div class="error-message">
        <h3>游戏加载失败</h3>
        <p>{{ error }}</p>
        <button class="btn btn-primary" @click="retryInit">重试</button>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, onUnmounted, watch, nextTick } from 'vue'
import { GameEngine } from '@/game'

/**
 * 游戏画布组件
 * 负责渲染游戏内容和处理用户输入
 * @component
 */

interface Props {
  /** 画布ID */
  canvasId?: string
  /** 画布宽度 */
  width?: number
  /** 画布高度 */
  height?: number
  /** 目标FPS */
  targetFPS?: number
  /** 是否自动开始游戏 */
  autoStart?: boolean
}

const props = withDefaults(defineProps<Props>(), {
  canvasId: 'game-canvas',
  width: 800,
  height: 400,
  targetFPS: 60,
  autoStart: true
})

const emit = defineEmits([
  'engine-ready',
  'engine-error', 
  'key-down',
  'key-up',
  'canvas-click'
])

// 响应式数据
const canvasRef = ref<HTMLCanvasElement>()
const isLoading = ref(false)
const error = ref<string>('')
const gameEngine = ref<GameEngine | null>(null)

// 计算属性
const canvasWidth = ref(props.width)
const canvasHeight = ref(props.height)

/**
 * 初始化游戏引擎
 */
const initGameEngine = async (): Promise<void> => {
  if (!canvasRef.value) {
    throw new Error('Canvas元素未找到')
  }

  try {
    isLoading.value = true
    error.value = ''

    // 等待下一个tick确保DOM已更新
    await nextTick()

    // 创建游戏引擎实例
    gameEngine.value = new GameEngine({
      canvasId: props.canvasId,
      width: canvasWidth.value,
      height: canvasHeight.value,
      targetFPS: props.targetFPS
    })

    // 如果设置了自动开始，则启动游戏
    if (props.autoStart) {
      gameEngine.value.start()
    }

    if (gameEngine.value) {
      emit('engine-ready', gameEngine.value)
    }
    console.log('游戏引擎初始化成功')
  } catch (err) {
    const errorMessage = err instanceof Error ? err.message : '未知错误'
    error.value = errorMessage
    emit('engine-error', err as Error)
    console.error('游戏引擎初始化失败:', err)
  } finally {
    isLoading.value = false
  }
}

/**
 * 重试初始化
 */
const retryInit = (): void => {
  initGameEngine()
}

/**
 * 处理画布点击事件
 * @param event - 鼠标事件
 */
const handleCanvasClick = (event: MouseEvent): void => {
  emit('canvas-click', event)
}

/**
 * 处理键盘按下事件
 * @param event - 键盘事件
 */
const handleKeyDown = (event: KeyboardEvent): void => {
  emit('key-down', event)
}

/**
 * 处理键盘释放事件
 * @param event - 键盘事件
 */
const handleKeyUp = (event: KeyboardEvent): void => {
  emit('key-up', event)
}

/**
 * 调整画布大小 - 全屏模式
 */
const resizeCanvas = (): void => {
  if (!canvasRef.value) return

  // 全屏模式：画布填充整个屏幕
  const screenWidth = window.innerWidth
  const screenHeight = window.innerHeight
  
  // 设置画布为全屏尺寸
  canvasWidth.value = screenWidth
  canvasHeight.value = screenHeight
  
  // 确保画布元素也是全屏尺寸
  if (canvasRef.value) {
    canvasRef.value.style.width = `${screenWidth}px`
    canvasRef.value.style.height = `${screenHeight}px`
  }
  
  console.log(`画布尺寸调整为全屏: ${screenWidth} x ${screenHeight}`)
}

// 监听窗口大小变化
const handleResize = (): void => {
  resizeCanvas()
}

// 生命周期钩子
onMounted(async () => {
  // 设置初始画布大小
  resizeCanvas()
  
  // 监听窗口大小变化
  window.addEventListener('resize', handleResize)
  
  // 初始化游戏引擎
  await initGameEngine()
  
  // 聚焦画布以接收键盘事件
  if (canvasRef.value) {
    canvasRef.value.focus()
  }
})

onUnmounted(() => {
  // 清理事件监听器
  window.removeEventListener('resize', handleResize)
  
  // 停止游戏引擎
  if (gameEngine.value) {
    gameEngine.value.stop()
    gameEngine.value = null
    console.log('游戏引擎已停止并清理')
  }
})

// 监听props变化
watch(() => [props.width, props.height], () => {
  resizeCanvas()
})

// 暴露方法给父组件
defineExpose({
  gameEngine: gameEngine.value,
  retryInit,
  resizeCanvas
})
</script>

<style lang="scss" scoped>
@import '@/styles/responsive.scss';

.game-canvas-container {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  width: 100vw;
  height: 100vh;
  display: block;
  background-color: #000;
  overflow: hidden;

  .game-canvas {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    display: block;
    background: linear-gradient(to bottom, #87CEEB 0%, #98FB98 100%);
    border-radius: 0;
    box-shadow: none;
    outline: none;
    cursor: crosshair;
    
    // 确保画布完全填充屏幕
    @include mobile-all {
      position: fixed;
      top: 0;
      left: 0;
      right: 0;
      bottom: 0;
      width: 100vw;
      height: 100vh;
      height: -webkit-fill-available;
      border-radius: 0;
      box-shadow: none;
      cursor: default;
      margin: 0;
      padding: 0;
    }
    
    // 桌面端也使用全屏
    @include desktop-all {
      position: fixed;
      top: 0;
      left: 0;
      right: 0;
      bottom: 0;
      width: 100vw;
      height: 100vh;
      border-radius: 0;
      box-shadow: none;
      margin: 0;
      padding: 0;
    }

    &:focus {
      box-shadow: 0 0 0 3px rgba($primary-color, 0.3);
      
      @include mobile-all {
        // 移动端不显示焦点样式
        box-shadow: none;
      }
    }
    
    // 触摸设备优化
    @include touch-device {
      // 禁用触摸时的高亮效果
      -webkit-tap-highlight-color: transparent;
      // 禁用长按菜单
      -webkit-touch-callout: none;
      // 禁用选择
      -webkit-user-select: none;
      -moz-user-select: none;
      -ms-user-select: none;
      user-select: none;
    }
  }

  .loading-overlay,
  .error-overlay {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    background-color: rgba(0, 0, 0, 0.8);
    color: white;
    z-index: 10;
    
    // 移动端安全区域适配
    @include mobile-all {
      padding: env(safe-area-inset-top, 1rem) env(safe-area-inset-right, 1rem) 
               env(safe-area-inset-bottom, 1rem) env(safe-area-inset-left, 1rem);
    }
  }

  .loading-spinner {
    width: 40px;
    height: 40px;
    border: 4px solid rgba(255, 255, 255, 0.3);
    border-top: 4px solid $primary-color;
    border-radius: 50%;
    animation: spin 1s linear infinite;
    margin-bottom: 1rem;
    
    @include mobile-all {
      width: 32px;
      height: 32px;
      border-width: 3px;
    }
  }

  .error-message {
    text-align: center;
    max-width: 300px;
    
    @include mobile-all {
      max-width: 280px;
      padding: 0 1rem;
    }

    h3 {
      color: $danger-color;
      margin-bottom: 1rem;
      font-size: 1.5rem;
      
      @include mobile-all {
        font-size: 1.3rem;
      }
    }

    p {
      margin-bottom: 1.5rem;
      opacity: 0.8;
      line-height: 1.5;
      
      @include mobile-all {
        font-size: 0.9rem;
        margin-bottom: 1rem;
      }
    }

    .btn {
      padding: 0.75rem 1.5rem;
      background-color: $primary-color;
      color: white;
      border: none;
      border-radius: $border-radius-md;
      cursor: pointer;
      transition: $transition-normal;
      font-size: 1rem;
      
      @include mobile-all {
        padding: 1rem 2rem;
        font-size: 1.1rem;
        width: 100%;
      }
      
      @include touch-device {
        min-height: 44px;
        
        &:active {
          background-color: darken($primary-color, 15%);
          transform: scale(0.98);
        }
      }

      @include non-touch-device {
        &:hover {
          background-color: darken($primary-color, 10%);
        }
      }
    }
  }
}

@keyframes spin {
  0% { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}

// 横屏模式优化
@include landscape {
  @include mobile-all {
    .game-canvas-container {
      .loading-overlay,
      .error-overlay {
        .error-message {
          h3 {
            font-size: 1.2rem;
          }
          
          p {
            font-size: 0.85rem;
          }
          
          .btn {
            padding: 0.75rem 1.5rem;
            font-size: 1rem;
          }
        }
      }
    }
  }
}
</style>